home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Viewers / aa_m68k_Intel_Only / ToyViewer1.2 / Source / TVController.m < prev    next >
Encoding:
Text File  |  1995-11-12  |  7.9 KB  |  355 lines

  1. #import <appkit/OpenPanel.h>
  2. #import <appkit/publicWraps.h>
  3. #import <appkit/Application.h>
  4. #import <appkit/NXImage.h>
  5. #import <appkit/PrintInfo.h>
  6. #import <appkit/Pasteboard.h>
  7. #import <stdio.h>
  8. #import <stdlib.h>
  9. #import <string.h>
  10. #import <sys/types.h>
  11. #import <sys/stat.h>
  12. #import <sys/file.h>
  13. #import "TVController.h"
  14. #import "PrefControl.h"
  15. #import "ToyWin.h"
  16. #import "ToyWinPPM.h"
  17. #import "ToyWinEPS.h"
  18. #import "ToyWinBMP.h"
  19. #import "ToyWinGIF.h"
  20. #import "ToyWinPCD.h"
  21. #import "DirList.h"
  22. #import "ADController.h"
  23. #import "strfunc.h"
  24. #import "Exttab.h"
  25. #import "common.h"
  26.  
  27. @implementation TVController
  28.  
  29. static int winCounter = 5; /* because small window is under the menu */
  30.  
  31. #define  typeNumber    16
  32.  
  33. /* ToyViewer treats these extensions as pre-defined */
  34. static const char *const fileType[typeNumber + 1] = {
  35.     "tiff", "tif", "TIFF", "TIF",
  36.     "eps", "EPS",
  37.     "gif", "GIF",
  38.     "bmp", "BMP",
  39.     "ppm", "pgm", "pbm", "pnm",
  40.     "pcd", "PCD",
  41.     NULL };
  42. static const char fileTypeID[typeNumber] = {
  43.     Type_tiff, Type_tiff, Type_tiff, Type_tiff,
  44.     Type_eps, Type_eps,
  45.     Type_gif, Type_gif,
  46.     Type_bmp, Type_bmp,
  47.     Type_ppm, Type_ppm, Type_ppm, Type_ppm,
  48.     Type_pcd, Type_pcd };
  49. static const char **fileTypeBuffer;
  50. static short *fileTypeIDBuffer;
  51. static char odir[MAXFILENAMELEN];    /* Last Opened Directory */
  52. static Exttab *extTable;
  53.  
  54.  
  55. /* If file has no extension, this func. recognize its file type */
  56. static int discriminate(const char *fn)
  57. {
  58.     int maybe = Type_none;
  59.     int cc;
  60.     FILE *fp;
  61.  
  62.     if ((fp = fopen(fn, "r")) == NULL)
  63.         return Type_none;
  64.     switch (cc = getc(fp)) {
  65.     case 0x0a: maybe = Type_pcx;  break;
  66.     case '%':  maybe = Type_eps;  break;
  67.     case 'B':  maybe = Type_bmp;  break;
  68.     case 'G':  maybe = Type_gif;  break;
  69.     case 'I':  maybe = Type_tiff;  break;
  70.     case 'M':  maybe = Type_mag;  break;
  71.     case 'P':  maybe = Type_ppm;  break;
  72.     case 0xff:
  73.         if (getc(fp) == 0xd8)
  74.             maybe = Type_jpg;
  75.         break;
  76.     default: break;
  77.     }
  78.     fclose(fp);
  79.     return maybe;
  80. }
  81.  
  82.  
  83. - appDidInit:sender
  84. {
  85.     int i, j, n;
  86.     char buf[256], *p, **q;
  87.     NXCoord    lmg, rmg, tmg, bmg;
  88.     const char *const *types = [NXImage imageFileTypes];
  89.  
  90.     [preference init];
  91.  
  92.     extTable = [[Exttab alloc] init];
  93.     n = dircopy(buf, NXArgv[0], YES);
  94.     strcpy(&buf[n], toyviewerTAB);
  95.     [extTable readExtData: buf];
  96.     p = getenv("HOME");
  97.     sprintf(buf, "%s/%s", p, toyviewerRC);
  98.     [extTable readExtData: buf];
  99.     sprintf(buf, "%s/Library/ToyViewer/%s", p, toyviewerRC);
  100.     [extTable readExtData: buf];
  101.     n = [extTable entry];
  102.  
  103.     for (i = 0; types[i]; i++) ;
  104.     n += i + typeNumber + 1;
  105.     fileTypeBuffer = (const char **)malloc(sizeof(char *const *) * n);
  106.     fileTypeIDBuffer = (short *)malloc(sizeof(short) * n);
  107.     i = 0;
  108.     if ((q = [extTable table]) != NULL)
  109.         for (j = 0; q[j]; j++) {
  110.             fileTypeBuffer[i] = q[j];
  111.             fileTypeIDBuffer[i++] = Type_user;
  112.         }
  113.     for (j = 0; fileType[j]; j++) {
  114.         fileTypeBuffer[i] = fileType[j];
  115.         fileTypeIDBuffer[i++] = fileTypeID[j];
  116.     }
  117.     for (j = 0; types[j]; j++) {
  118.         fileTypeBuffer[i] = types[j];
  119.         fileTypeIDBuffer[i++] = Type_other;
  120.     }
  121.     fileTypeBuffer[i] = NULL;
  122.     [DirList setExtList: fileTypeBuffer];
  123.  
  124.     printInfo = [NXApp printInfo];
  125.     [printInfo setOrientation:NX_LANDSCAPE andAdjust:YES];
  126.     [printInfo getMarginLeft:&lmg right:&rmg top:&tmg bottom:&bmg];
  127.     lmg = (lmg + rmg) * 0.3;
  128.     tmg = (tmg + bmg) * 0.3;
  129.     [printInfo setMarginLeft:lmg right:lmg top:tmg bottom:tmg];
  130.     return self;
  131. }
  132.  
  133.  
  134. - drawFile: (const char *)fn :(const char *)aType
  135.     /* Return Value:  nil: Error,  id: New ToyWin */
  136. {
  137.     id twtmp = nil;
  138.     int i, err;
  139.     int itype = Type_none;
  140.     const char *key = NULL;
  141.  
  142.     // if ([self isOpened: fn]) return self;
  143.     if (aType && *aType) {
  144.         for (i = 0; fileTypeBuffer[i]; i++)
  145.             if (strcmp(aType, fileTypeBuffer[i]) == 0) {
  146.                 itype =  fileTypeIDBuffer[i];
  147.                 key = aType;
  148.                 break;
  149.             }
  150.     }
  151.     if (itype == Type_none) { /* Unknown Extension */
  152.         if ((itype = discriminate(fn)) == Type_none)
  153.             return nil;
  154.     }
  155.  
  156.     if (viaPipe(itype)) { /* Type_user and ... */
  157.         if (key == NULL)
  158.             switch (itype) {
  159.             case Type_pcx:    key = "pcx"; break;
  160.             case Type_mag:    key = "mag"; break;
  161.             case Type_jpg:    key = "jpg"; break;
  162.             }
  163.         twtmp = [[ToyWinPPM alloc] init: self];
  164.         [twtmp setExecList:
  165.             [extTable execListAlloc: key with: fn] ext: key]; 
  166.     }else if (itype == Type_pcd) {
  167.         twtmp = [[ToyWinPCD alloc] init: self];
  168.         [twtmp setPreference: preference];
  169.     }else {
  170.         switch (itype) {
  171.         case Type_bmp:
  172.             twtmp = [ToyWinBMP alloc]; break;
  173.         case Type_gif:
  174.             twtmp = [ToyWinGIF alloc]; break;
  175.         case Type_eps:
  176.             twtmp = [ToyWinEPS alloc]; break;
  177.         case Type_ppm:
  178.             twtmp = [ToyWinPPM alloc]; break;
  179.         case Type_tiff:
  180.         case Type_other:
  181.         default:
  182.             twtmp = [ToyWin alloc]; break;
  183.         }
  184.         [twtmp init: self];
  185.     }
  186.  
  187.     err = [twtmp drawToyWin:(const char *)fn Type:itype Num:winCounter];
  188.     if (err == 0) {
  189.         [self newWindow: twtmp];
  190.         winCounter++;
  191.     }else {
  192.         if (err > 0)
  193.             errAlert(fn, err);
  194.         [twtmp free];
  195.         return nil;
  196.     }
  197.     return twtmp;    // return New ToyWin
  198. }
  199.  
  200. - openFile:sender
  201. {
  202.     char fn[MAXFILENAMELEN];
  203.     id openPanel;
  204.     
  205.     if (!odir[0])
  206.         strcpy(odir, getenv("HOME"));
  207.     openPanel = [OpenPanel new];
  208.     [[openPanel chooseDirectories: NO] allowMultipleFiles:YES];
  209.     if ([openPanel runModalForDirectory:odir
  210.             file:NULL types:fileTypeBuffer]) {
  211.         const char *const *files = [openPanel filenames];
  212.         strcpy(odir, [openPanel directory]);
  213.         for ( ; files && *files; files++) {
  214.             sprintf(fn, "%s/%s", odir, *files);
  215.             if (! [self isOpened: fn]) {
  216.                 int j;
  217.                 if ((j = getExtension(fn)) == 0)
  218.                     return self; /* No Extension */
  219.                 [self drawFile: fn : &fn[j]];
  220.             }
  221.         }
  222.     }
  223.     return self;
  224. }
  225.  
  226. #define  AutoThreshold    4
  227.  
  228. /* Local Method */
  229. - openDirectory: (const char *)dir
  230. {
  231.     char fn[MAXFILENAMELEN];
  232.     const char *p;
  233.     int    n, i;
  234.     id    dirlist;
  235.  
  236.     dirlist = [[DirList alloc] init];
  237.     n = [dirlist getDirList: dir];
  238.     if (n <= 0) {
  239.         errAlert(dir, Err_NOFILE);
  240.         [dirlist free];
  241.     }else if (n < AutoThreshold) {
  242.         for (i = 0; i < n; i++) {
  243.             p = [dirlist filenameAt: i];
  244.             sprintf(fn, "%s/%s", dir, p);
  245.             if (! [self isOpened: fn]) {
  246.                 int j = getExtension(p);
  247.                 (void)[self drawFile: fn : &p[j]];
  248.             }
  249.         }
  250.         [dirlist free];
  251.     }else { /* Auto Display */
  252.         ADController *ad = [ADController alloc];
  253.         [ad init:self dir:dir with:dirlist];
  254.     }
  255.  
  256.     return self;
  257. }
  258.  
  259. - autoDisplay:sender
  260. {
  261.     char fn[MAXFILENAMELEN];
  262.     id openPanel;
  263.     const char *const *files;
  264.  
  265.     if (!odir[0])
  266.         strcpy(odir, getenv("HOME"));
  267.     openPanel = [OpenPanel new];
  268.     [[openPanel chooseDirectories: YES] allowMultipleFiles:NO];
  269.     if (![openPanel runModalForDirectory:odir file:NULL])
  270.         return self;
  271.  
  272.     files = [openPanel filenames];
  273.     strcpy(odir, [openPanel directory]);
  274.     sprintf(fn, "%s/%s", odir, *files);
  275.     [self openDirectory: fn];
  276.     return self;
  277. }
  278.  
  279. - openPasteBoard:sender
  280. {
  281.     Pasteboard    *pb;
  282.     const NXAtom    *cont;
  283.     NXStream    *st;
  284.     id   twtmp = nil;
  285.     char *ext, fn[256];
  286.     int  err;
  287.     static int untitledCount = 0;
  288.  
  289.     pb = [Pasteboard new];  // don't free it
  290.     ext = NULL;
  291.     for (cont = [pb types]; cont && *cont; cont++) {
  292.         if (*cont == NXTIFFPboardType) {
  293.             twtmp = [[ToyWin alloc] init: self];
  294.             ext = "tiff";
  295.             break;
  296.         }
  297.         if (*cont == NXPostScriptPboardType) {
  298.             twtmp = [[ToyWinEPS alloc] init: self];
  299.             ext = "eps";
  300.             break;
  301.         }
  302.     }
  303.     if (ext == NULL) {
  304.         NXBeep();
  305.         return self;
  306.     }
  307.     st = [pb readTypeToStream: *cont];
  308.     sprintf(fn, "%s/Untitled%d.%s", getenv("HOME"), ++untitledCount, ext);
  309.  
  310.     err = [twtmp drawFromFile:(const char *)fn or:st Num:winCounter];
  311.     if (err == 0) {
  312.         [self newWindow: twtmp];
  313.         winCounter++;
  314.     }else {
  315.         if (err > 0)
  316.             errAlert(fn, err);
  317.         [twtmp free];
  318.     }
  319.     NXCloseMemory(st, NX_FREEBUFFER);
  320.     return self;
  321. }
  322.  
  323.  
  324. - (int)app:sender openFile:(const char *)fn type:(const char *)aType
  325. {
  326.     struct stat  buf;
  327.     int    mode;
  328.     id    res = nil;
  329.  
  330.     if (printInfo == nil)
  331.         [self appDidInit:sender];
  332.     if (stat((char *)fn, &buf) != 0) return NO;
  333.     mode = (buf.st_mode & S_IFMT);
  334.     if (mode == S_IFDIR) {
  335.         if (access(fn, X_OK) != 0) return NO;
  336.         res = [self openDirectory: fn];
  337.     }else {
  338.         if ([self isOpened: fn]) return YES;
  339.         res = [self drawFile: fn : aType];
  340.     }
  341.     return (res != nil);
  342. }
  343.  
  344. - (BOOL)appAcceptsAnotherFile:sender
  345. {
  346.     return YES;
  347. }
  348.  
  349. - preference
  350. {
  351.     return preference;
  352. }
  353.  
  354. @end
  355.